{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Teleoperation\n",
    "\n",
    "In this example we'll control the Jetbot remotely with a gamepad controller connected to our web browser machine."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Create gamepad controller\n",
    "\n",
    "The first thing we want to do is create an instance of the ``Controller`` widget, which we'll use to drive our robot.\n",
    "The ``Controller`` widget takes a ``index`` parameter, which specifies the number of the controller.  This is useful in case you\n",
    "have multiple controllers attached, or some gamepads *appear* as multiple controllers.  To determine the index\n",
    "of the controller you're using,\n",
    "\n",
    "1. Visit [http://html5gamepad.com](http://html5gamepad.com).  \n",
    "2. Press buttons on the gamepad you're using\n",
    "3. Remember the ``index`` of the gamepad that is responding to the button presses\n",
    "\n",
    "Next, we'll create and display our controller using that index."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "b981249dafe74786aa99730cf09dcc7f",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Controller()"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import ipywidgets.widgets as widgets\n",
    "\n",
    "controller = widgets.Controller(index=0)  # replace with index of your controller\n",
    "\n",
    "display(controller)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Even if the index is correct, you may see the text ``Connect gamepad and press any button``.  That's because the gamepad hasn't\n",
    "registered with this notebook yet.  Press a button and you should see the gamepad widget appear above."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Connect gamepad controller to robot motors\n",
    "\n",
    "Now, even though we've connected our gamepad, we haven't yet attached the controls to our robot!  The first, and most simple control\n",
    "we want to attach is the motor control.  We'll connect that to the left and right vertical axes using the ``dlink`` function.  The\n",
    "``dlink`` function, unlike the ``link`` function, allows us to attach a transform between the ``source`` and ``target``.  Because\n",
    "the controller axes are flipped from what we think is intuitive for the motor control, we'll use a small *lambda* function to\n",
    "negate the value.\n",
    "\n",
    "> WARNING: This next cell will move the robot if you touch the gamepad controller axes!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from jetracer.nvidia_racecar import NvidiaRacecar\n",
    "import traitlets\n",
    "\n",
    "car = NvidiaRacecar()\n",
    "\n",
    "car.throttle_gain = 0.3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "car.steering_offset=-0.18\n",
    "car.steering = 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "left_link = traitlets.dlink((controller.axes[0], 'value'), (car, 'steering'), transform=lambda x: -x)\n",
    "right_link = traitlets.dlink((controller.axes[5], 'value'), (car, 'throttle'), transform=lambda x: -x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Awesome! Our robot should now respond to our gamepad controller movements.  Now we want to view the live video feed from the camera!"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
